/*
 * Copyright (C) 2022 Beken Corporation
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "core_v5.h"

	.section .nds_vector, "ax"

.option push
.option norelax
	.global reset_vector

reset_vector:
	/* Decide whether this is an NMI or cold reset */
	csrr t0, mcause
	bnez t0, nmi_handler
	.global _start
	.type _start,@function

_start:
#ifndef CACHE_DISABLE
   /* enable icache   */
    csrr	a5,mcache_ctl
     ori	a5,a5,1
    csrw	mcache_ctl,a5
   /* enable dcache */
    csrr	a5,mcache_ctl
     ori	a5,a5,2
    csrw	mcache_ctl,a5
#endif
	/* Initialize global pointer */
	.option push
	.option norelax
	la gp, __global_pointer$
	.option pop

	/* Initialize stack pointer */
	la t0, _stack
	mv sp, t0

#ifdef __nds_execit
	/* Initialize EXEC.IT table */
	la t0, _ITB_BASE_
	csrw uitb, t0
#endif

#ifdef __riscv_flen
	/* Enable FPU */
	li t0, MSTATUS_FS
	csrrs t0, mstatus, t0

	/* Initialize FCSR */
	fscsr zero
#endif

	/* Initial machine trap-vector Base. Use FreeRTOS trap function. */
    #ifdef INT_VECTOR_EN
	    la t0, __vectors
	#else
	    la t0, freertos_risc_v_trap_handler
    #endif
	csrw mtvec, t0

	/* Enable vectored external PLIC interrupt */
	#ifdef INT_VECTOR_EN
	    csrsi mmisc_ctl, 2
	#endif

#ifndef CACHE_DISABLE
	/* Enable I/D cache with HW prefetcher and D-cache write-around (threshold: 4 cache lines) */
	li t0, (0x3 << 13)
	csrc mcache_ctl, t0
	li t0, (1 << 13) | (1 << 10) | (1 << 9) | (0x3)
	csrs mcache_ctl, t0
#endif

	/* Do system low level setup. It must be a leaf function */
	call __platform_init

	/* System reset handler */
	call reset_handler

	/* Infinite loop, if returned accidently */
1:	j 1b

	.weak __platform_init
__platform_init:
	ret


	.weak nmi_handler
nmi_handler:
	csrr a0, mcause
	mv  a1, ra
	call user_nmi_handler
	li t0, TRAP_M_USER_NP
	csrw mcause, t0
	j freertos_risc_v_trap_handler
	ret

.org  0x100
.word 0x32374B42
.word 0x00003635
.word 0x00000000
.word 0x00000000
.org  0x110
.word 0x64616568    /*head: sign head address*/
.word 0x00000000
.word 0x00000000
.word 0x00000000
.org  0x120
.word 0x00000000    /*version: provide to version number setting*/
.word 0x00000000
.word 0x00000000
.word 0x00000000
.option pop
	.section .text

	.global trap_entry
	.align 2

trap_entry:
	li t0, TRAP_M_USER_ASSERT
	csrw mcause, t0
	j freertos_risc_v_trap_handler
	ret

#ifdef INT_VECTOR_EN
	.text

	.global default_irq_entry
	.align 2

default_irq_entry:
1:	j 1b

.macro INTERRUPT num
	.weak entry_irq\num
	.set entry_irq\num, default_irq_entry
	.long entry_irq\num
	.endm

	/* Vector table
	 * NOTE:
	 * The Vector Table base alignment requirement has to be :
	 * " 2^ceiling(log2(N)) x 4 " bytes,
	 * if the PLIC device supports N interrupt sources.
	 */
#define VECTOR_NUMINTRS         63
	.section .vector_table, "a"

	.global __vectors
//	.balign 4096
    .balign 128
__vectors:
	/* Trap vector */
	.long trap_entry

	/* PLIC interrupt vector */
	.altmacro
	.set irqno, 1
	.rept VECTOR_NUMINTRS
	INTERRUPT %irqno
	.set irqno, irqno+1
	.endr
#endif
